#include <iostream>
#include <math.h>
typedef struct
{
	double re;
	double im;
}Complex;
const Complex zero={0.0,0.0};

Complex adComplex(Complex a,Complex b);
Complex ad2Complex(Complex *a,Complex *b);
Complex diff(Complex a,Complex b);
Complex diff2(Complex *a,Complex *b);
void print1(Complex);
bool equals(Complex a,Complex b);
bool equals1(Complex a);
bool null(Complex a);

inline void print(Complex p)
{
	std::cout<<"\n Re="<<p.re<<",Im="<<p.im<<"\n";
}

double modul(Complex p)
{
	return sqrt((p.re*p.re+p.im*p.im));
}

double arg(Complex p)
{
	return atan(p.im/p.re);
}


int main()
{
	//Testarea onstructiuni print si a constantei zero
	print(zero);
	//Construirea unui obiect Complex si calcularea modulului sau
	Complex Z1={3.0,4.0};
	print(Z1);
	std::cout<<"Modulul numarului de mai sus este:"<<modul(Z1)<<"\n";
	//Metoda I de adunare
	Complex Z2={2.3,3.1};
	Complex s1=adComplex(Z1,Z2);
	print(s1);
	//Metoda II de adunare
	Complex *m=&Z1;
	Complex *n=&Z2;
	Complex s2=ad2Complex(m,n);
	print(s2);
	//Testarea primei metode de scadere
	Complex d1=diff(Z1,Z2);
	print(d1);
	//Testarea celei de a doua metode de scadere
	Complex *p=&Z1;
	Complex *q=&Z2;
	Complex d2=diff2(p,q);
	print(d2);
	//Print
	print1(Z1);
	print1(Z2);
	//Testarea metodei de egalitate
	if(equals(Z1,Z2))
	std::cout<<"\n Numerele Z1 si Z2 sunt egale\n";
	else
	std::cout<<"\n Numerele Z1 si Z2 nu sunt egale\n";
	//Testarea obiectelor nule
	if(null(Z1))
	std::cout<<"\nZ1 este nul\n";
	else
	std::cout<<"\nZ1 nu este nul\n";
	if(null(Z2))
	std::cout<<"\nZ2 este nul\n";
	else
	std::cout<<"\nZ2 nu este nul\n";
	Complex Z3={0.0,0.0};
	print(Z3);
	if(null(Z3))
	std::cout<<"\nZ3 este nul\n";
	else
	std::cout<<"\nZ3 nu este nul\n";

	return 0;
}

//Functia care calculeaza suma a doua numere complexe

Complex adComplex(Complex a,Complex b)
{
	double x,y;
	x=a.re+b.re;
	y=a.im+b.im;
	Complex s={x,y};
	return s;
}

//Functia care calculeaza suma a doua numere complexe
Complex ad2Complex(Complex *a,Complex *b)
{
	double x,y;
	x=(*a).re+(*b).re;
	y=(*a).im+(*b).im;
	Complex s={x,y};
	return s;
}

//Functia care calculeaza diferenta a doua numere Complexe
Complex diff(Complex a,Complex b)
{
	double x,y;
	x=a.re-b.re;
	y=a.im-b.im;
	Complex s={x,y};
	return s;
}

//Functia care calculeaza diferenta a doua numere Complexe
Complex diff2(Complex *a,Complex *b)
{
	double x,y;
	x=(*a).re-(*b).re;
	y=(*a).im-(*b).im;
	Complex s={x,y};
	return s;
}

//Print
void print1(Complex p=zero)
{
	std::cout<<"\n p.real="<<p.re<<" & "<<"p.imag="<<p.im<<"\n";
}

//Functia care testeaza daca numerele complexe sunt egale
bool equals(Complex a,Complex b)
{
	if((a.re==b.re)&&(a.im==b.im))
	return true;
	else
	return false;
}

bool equals1(Complex a)
{
	if((a.re==0.0)&&(a.im==0.0))
	return true;
	else
	return false;
}

//Functia obiectelor nule
bool null(Complex a)
{
	if(equals1(a))
	return true;
	else
	return false;
}
